package com.huilian.iotbox.admin.wap.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.huilian.iotbox.admin.wap.dao.DeviceDao;
import com.huilian.iotbox.admin.wap.dao.OrderDao;
import com.huilian.iotbox.admin.wap.dao.StatsCommodityStockRecordDao;
import com.huilian.iotbox.admin.wap.dao.StatsUserDao;
import com.huilian.iotbox.admin.wap.service.*;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.dto.*;
import com.huilian.iotbox.data.enums.*;
import com.huilian.iotbox.data.po.Order;
import com.huilian.iotbox.data.utils.DateTimeUtils;
import com.huilian.iotbox.data.utils.SciCalUtils;
import com.huilian.iotbox.data.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 谢洛涛
 * @date 2021/1/18 11:31
 */
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderDao orderDao;
    @Autowired
    private StatsUserService statsUserService;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private CommodityStockRecordService commodityStockRecordService;
    @Autowired
    private DeviceDao deviceDao;
    @Autowired
    private DisplayRackItemService displayRackItemService;
    @Autowired
    private StatsUserDao statsUserDao;
    @Autowired
    private StatsCommodityStockRecordDao statsCommodityStockRecordDao;

    @Override
    public PageInfo findOrderList(OrderDto orderDto) {
        PageHelper.startPage(orderDto.getPageNum(), orderDto.getPageSize());
        List<OrderVo> orderList = orderDao.findOrderList(orderDto);
        PageInfo pagResult = new PageInfo(orderList);
        return pagResult;
    }

    @Override
    public ServerResponse statisticsDayIncome(OrderDto orderDto) {
        // 统计order表的金额
        orderDto.setStartTime(DateTimeUtils.getTodayStartTime());
        orderDto.setEndTime(DateTimeUtils.getTodayEndTime());
        BigDecimal orderTotalMoney = orderDao.statisticsDayIncome(orderDto);

        // 统计activity_order表的金额
        StatsUserDto statsUserDto = new StatsUserDto();
        statsUserDto.setStartTime(DateTimeUtils.getTodayStartTime());
        statsUserDto.setEndTime(DateTimeUtils.getTodayEndTime());
        statsUserDto.setUserInfo(orderDto.getUserInfo());
        StatsUserVo activityStatsUser = statsUserService.findActivityMoney(statsUserDto);

        if (StringUtils.isEmpty(activityStatsUser)) {
            activityStatsUser.setActivityTurnover(BigDecimal.ZERO);
        }
        BigDecimal totalMoney = orderTotalMoney.add(activityStatsUser.getActivityTurnover());
        return ServerResponse.createBySuccess(totalMoney);
    }

    @Override
    public ServerResponse findOneOrderByOutTradeNo(OrderDto orderDto) {
        OrderVo order = orderDao.findOneOrderByOutTradeNo(orderDto.getOutTradeNo(), orderDto.getUserInfo());
        if (ObjectUtils.isEmpty(order)) {
            return ServerResponse.createByErrorMessage("获取数据失败，请重新进入");
        }
        return ServerResponse.createBySuccess(order);
    }

    @Override
    public OrderVo findOneOrderByOutTradeNo(String outTradeNo, UserInfo userInfo) {
        return orderDao.findOneOrderByOutTradeNo(outTradeNo, userInfo);
    }


    @Override
    public List<OrderVo> findDenominationCountByDeviceNo(OrderDto orderDenomination) {
        return orderDao.findDenominationCountByDeviceNo(orderDenomination);
    }

    @Override
    public List<OrderVo> findDenominationCountByMerchantStoreId(OrderDto orderDenomination) {
        return orderDao.findDenominationCountByMerchantStoreId(orderDenomination);
    }

    /**
     * 订单查询-小程序
     *
     * @param orderDto
     * @return
     */
    @Override
    public ServerResponse findOrderListByApplet(OrderDto orderDto) {
        if (StringUtils.isEmpty(orderDto.getTabsMenuCurrent())) {
            return ServerResponse.createByErrorMessage("缺少查询坐标");
        }
        if (orderDto.getTabsMenuCurrent().compareTo(OrderTypeEnum.ORDINARY_ORDER.getCode()) == 0) {
            orderDto.setMchTypeArray(new Integer[]{
                    MchTypeEnum.OWN.getCode(),
                    MchTypeEnum.CASH_RECEIPTS.getCode(),
                    MchTypeEnum.OFFLINE_COLLECTION_CODE.getCode(),
                    MchTypeEnum.CUSTOMIZED_POS_COLLECTION.getCode(),
            });
        } else if (orderDto.getTabsMenuCurrent().compareTo(OrderTypeEnum.MEI_TUAN_ORDER.getCode()) == 0) {
            orderDto.setMchTypeArray(new Integer[]{
                    MchTypeEnum.MEITUAN_GROUP_PURCHASE.getCode(),
            });
        } else if (orderDto.getTabsMenuCurrent().compareTo(OrderTypeEnum.DOU_YIN_ORDER.getCode()) == 0) {
            orderDto.setMchTypeArray(new Integer[]{
                    MchTypeEnum.DOUYIN_GROUP_PURCHASE.getCode(),
            });
        } else {
            return ServerResponse.createByErrorMessage("不存在坐标");
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date startTime = null;
        Date endTime = null;
        try {
            startTime = format.parse(orderDto.getStartTime());
            endTime = format.parse(orderDto.getEndTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        orderDto.setGmtPaymentStart(startTime);
        orderDto.setGmtPaymentEnd(endTime);

        PageHelper.startPage(orderDto.getPageNum(), orderDto.getPageSize());
        List<OrderVo> orderList = orderDao.findOrderListByApplet(orderDto);
        PageInfo pagResult = new PageInfo(orderList);
        return ServerResponse.createBySuccess(pagResult);
    }

    /**
     * 订单查询，页头统计-小程序
     *
     * @param orderDto
     * @return
     */
    @Override
    public ServerResponse findOrderStatisticsByApplet(OrderDto orderDto) {
        if (StringUtils.isEmpty(orderDto.getTabsMenuCurrent())) {
            return ServerResponse.createByErrorMessage("缺少查询坐标");
        }
        if (orderDto.getTabsMenuCurrent().compareTo(OrderTypeEnum.ORDINARY_ORDER.getCode()) == 0) {
            orderDto.setMchTypeArray(new Integer[]{
                    MchTypeEnum.OWN.getCode(),
                    MchTypeEnum.CASH_RECEIPTS.getCode(),
                    MchTypeEnum.OFFLINE_COLLECTION_CODE.getCode(),
                    MchTypeEnum.CUSTOMIZED_POS_COLLECTION.getCode(),
            });
        } else if (orderDto.getTabsMenuCurrent().compareTo(OrderTypeEnum.MEI_TUAN_ORDER.getCode()) == 0) {
            orderDto.setMchTypeArray(new Integer[]{
                    MchTypeEnum.MEITUAN_GROUP_PURCHASE.getCode(),
            });
        } else if (orderDto.getTabsMenuCurrent().compareTo(OrderTypeEnum.DOU_YIN_ORDER.getCode()) == 0) {
            orderDto.setMchTypeArray(new Integer[]{
                    MchTypeEnum.DOUYIN_GROUP_PURCHASE.getCode(),
            });
        } else {
            return ServerResponse.createByErrorMessage("不存在坐标");
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date startTime = null;
        Date endTime = null;
        try {
            startTime = format.parse(orderDto.getStartTime());
            endTime = format.parse(orderDto.getEndTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        orderDto.setGmtPaymentStart(startTime);
        orderDto.setGmtPaymentEnd(endTime);
        OrderVo orderVo = orderDao.findOrderStatisticsByApplet(orderDto);
        return ServerResponse.createBySuccess(orderVo);
    }

    @Override
    public List<OrderVo> findDenominationCountByPermission(UserInfo userInfo, Integer[] merchantStoreIdArray, String startTime, String endTime) {

        String[] channelTypeArray = new String[]{
                ChannelTypeEnum.BILL_MACHINE.getCode(),
                ChannelTypeEnum.COIN_BOX.getCode()
        };
        Integer[] orderStatusArray = new Integer[]{
                OrderStatusEnum.SUCCESS.getCode(),
                OrderStatusEnum.PART_REFUND.getCode(),
                OrderStatusEnum.FULL_FERUND.getCode(),
                OrderStatusEnum.REFUNDING.getCode(),
        };

        OrderDto orderDenomination = new OrderDto();
        orderDenomination.setUserInfo(userInfo);
        orderDenomination.setMerchantStoreIdArray(merchantStoreIdArray);
        orderDenomination.setStartTime(startTime);
        orderDenomination.setEndTime(endTime);
        orderDenomination.setMchType(MchTypeEnum.CASH_RECEIPTS.getCode());
        orderDenomination.setChannelTypeArray(channelTypeArray);
        orderDenomination.setOrderStatusArray(orderStatusArray);
        orderDenomination.setTerminalType(OrderTerminalTypeEnum.SELF_HELP.getCode());
        return orderDao.findDenominationCountByPermission(orderDenomination);
    }

    @Override
    public List<OrderVo> findOrderListByBranch(OrderDto orderDto) {
        return orderDao.findOrderListByBranch(orderDto);
    }

    @Override
    public ServerResponse checkOrderCode(OrderDto orderDto) {
        Integer result = orderDao.checkOrderCode(orderDto);
        return ServerResponse.createBySuccess(result);
    }

    @Override
    public List<OrderVo> findOrderListCashAndOwn(OrderDto orderDto) {
        return orderDao.findOrderListCashAndOwn(orderDto);
    }

    @Override
    public ServerResponse updateRemark(OrderDto orderDto) {
        OrderVo orderVoList = orderDao.findOrderIdMerchantStore(orderDto);
        if (orderVoList != null) {
            Integer result = orderDao.updateRemark(orderDto);
            return ServerResponse.createBySuccess(result);
        }
        return ServerResponse.createByErrorMessage("未拥有该订单管理权限");
    }

    /**
     * 统计某个会员在某个场地或某几个场地的消费金额（order表、activity_order）
     *
     * @param userInfo
     * @param memberId
     * @param merchantStoreId
     * @return
     */
    @Override
    public OrderVo statisticsOneMemberAllTurnoverByMemberId(UserInfo userInfo, Long memberId, Integer merchantStoreId) {
        OrderVo orderVo = new OrderVo();

        /**
         * 查询order、activity_order表当天的消费金额-begin
         */
        int[] mchTypeArray = new int[]{
                MchTypeEnum.OWN.getCode(),
                MchTypeEnum.PLATFORM.getCode(),
                MchTypeEnum.CASH_RECEIPTS.getCode(),
                MchTypeEnum.DOUYIN_GROUP_PURCHASE.getCode(),
                MchTypeEnum.MEITUAN_GROUP_PURCHASE.getCode(),
        };
        BigDecimal todayOrderTurnover = orderDao.statisticsOneMemberAllTurnoverByMemberId(userInfo, memberId, merchantStoreId, mchTypeArray);
        if (StringUtils.isEmpty(todayOrderTurnover)) {
            todayOrderTurnover = BigDecimal.ZERO;
        }
        log.info("todayOrderTurnover{}:", todayOrderTurnover);


        orderVo.setTurnover(todayOrderTurnover);
        return orderVo;
    }

    @Override
    public List<OrderVo> findOrderListByBranchScanCode(OrderDto orderDto) {
        return orderDao.findOrderListByBranchScanCode(orderDto);
    }

    @Override
    public ServerResponse findHeadStatisticsData(OrderDto orderDto) {


        /**
         * 统计当天的数据
         * */
        // 统计order表的金额
        orderDto.setStartTime(DateTimeUtils.getTodayStartTime());
        orderDto.setEndTime(DateTimeUtils.getTodayEndTime());
        OrderVo orderVoMoney = orderDao.statisticsDayData(orderDto);

        StatsUserDto statsUserDto = new StatsUserDto();
        statsUserDto.setStartTime(DateTimeUtils.getTodayStartTime());
        statsUserDto.setEndTime(DateTimeUtils.getTodayEndTime());
        statsUserDto.setUserInfo(orderDto.getUserInfo());

        //统计商品数
        OrderItemVo orderItemVo = orderItemService.findOrderItemDayStatistics(statsUserDto);
        //商品成本
        CommodityStockRecordDto commodityStockRecordDto = new CommodityStockRecordDto();
        commodityStockRecordDto.setUserInfo(orderDto.getUserInfo());
        commodityStockRecordDto.setSecondaryType(CommodityStockRecordSecondTypeEnum.VENDING_MACHINE_OUT.getCode());
        commodityStockRecordDto.setFirstType(CommodityStockRecordFirstTypeEnum.OUTBOUND.getCode());
        commodityStockRecordDto.setStartTime(DateTimeUtils.getTodayStartTime());
        commodityStockRecordDto.setEndTime(DateTimeUtils.getTodayEndTime());
        List<CommodityStockRecordVo> commodityStockRecordList = commodityStockRecordService.findCommodityStockRecordListByTime(commodityStockRecordDto);
        BigDecimal totalCostPrice = BigDecimal.ZERO;
        if (commodityStockRecordList != null && commodityStockRecordList.size() > 0) {
            totalCostPrice = commodityStockRecordList.stream()
                    .map(CommodityStockRecordVo::getTotalCostPrice)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }
        //设备数 在线 离线
        DeviceDto deviceDto = new DeviceDto();
        deviceDto.setUserInfo(orderDto.getUserInfo());
        deviceDto.setUserId(orderDto.getUserId());
        DeviceVo deviceVo = deviceDao.findStoreStats(deviceDto);
        //补货
        DisplayRackItemDto displayRackItemDto = new DisplayRackItemDto();
        displayRackItemDto.setUserInfo(orderDto.getUserInfo());
        displayRackItemDto.setUserId(orderDto.getUserId());
        DisplayRackItemVo displayRackItemVo = displayRackItemService.findOutOfStockByUserId(displayRackItemDto);


        String yesterday = DateTimeUtils.getYesterday();
        statsUserDto.setStatsType(1);
        statsUserDto.setEndDateStr(yesterday);
        statsUserDto.setStartDateStr(yesterday);
        statsUserDto.setType(1);
        StatsUserVo userVo = new StatsUserVo();
        if (orderDto.getUserInfo().getRoleId().compareTo(RoleEnum.SUB_ACCOUNT.getRoleId()) == 0) {
            //子账号
            if (orderDto.getUserInfo().getStoreIdList().size() > 0) {
                //统计昨天的数据
                //昨天日期 格式yyyy-MM-dd
                userVo = statsUserDao.findSubAccountStatsUser(statsUserDto);

                //统计过年每月数据
                StatsUserDto dto = new StatsUserDto();
                dto.setEndDateStr(DateTimeUtils.getMonthYM());
                dto.setType(2);
                dto.setStatsType(1);
                dto.setUserInfo(orderDto.getUserInfo());
                StatsUserVo orderTurnoverByEndDate = statsUserDao.findSubAccountOrderTurnoverByEndDate(dto);

                //统计当月每天数据
                dto.setType(1);
                dto.setEndDateStr(DateTimeUtils.getMonthLastDay());
                dto.setStartDateStr(DateTimeUtils.getMonthFirstDay());
                StatsUserVo statsUserVo = statsUserDao.findSubAccountStatsUser(dto);
                //合并数据
                userVo.setOrderTotalTurnover(orderTurnoverByEndDate.getTurnover().add(statsUserVo.getTurnover()));

            } else {
                userVo.setTurnover(BigDecimal.ZERO);
                userVo.setQuantityOfCoinsSold(0);
                userVo.setOrderCount(0);
                userVo.setOrderTotalTurnover(BigDecimal.ZERO);
            }
        } else {
            //主账号统计昨天的数据
            userVo = statsUserDao.findByUserId(statsUserDto);

            //统计过年每月数据
            StatsUserDto dto = new StatsUserDto();
            dto.setEndDateStr(DateTimeUtils.getMonthYM());
            dto.setType(2);
            dto.setStatsType(1);
            dto.setUserInfo(orderDto.getUserInfo());
            StatsUserVo orderTurnoverByUserIdAndEndDate = statsUserDao.findOrderTurnoverByUserIdAndEndDate(dto);

            //统计当月每天数据
            dto.setType(1);
            dto.setEndDateStr(DateTimeUtils.getMonthLastDay());
            dto.setStartDateStr(DateTimeUtils.getMonthFirstDay());
            StatsUserVo statsUserVo = statsUserDao.findByUserId(dto);
            //合并数据
            userVo.setOrderTotalTurnover(orderTurnoverByUserIdAndEndDate.getTurnover().add(statsUserVo.getTurnover()));
        }

        StatsUserVo statsUserVo = new StatsUserVo();
        /**
         * 返回昨天的数据
         * */
        StatsCommodityStockRecordDto statsCommodityStockRecordDto = new StatsCommodityStockRecordDto();
        statsCommodityStockRecordDto.setUserInfo(orderDto.getUserInfo());
        statsCommodityStockRecordDto.setSecondaryType(CommodityStockRecordSecondTypeEnum.VENDING_MACHINE_OUT.getCode());
        statsCommodityStockRecordDto.setFirstType(CommodityStockRecordFirstTypeEnum.OUTBOUND.getCode());
        statsCommodityStockRecordDto.setEndDateStr(yesterday);
        statsCommodityStockRecordDto.setStartDateStr(yesterday);
        statsCommodityStockRecordDto.setType(1);
        StatsCommodityStockRecordVo statsCommodityStockRecordVo = statsCommodityStockRecordDao.findStatsCommodityStockRecordSum(statsCommodityStockRecordDto);
        statsUserVo.setYesterdayTotalCommodityCount(statsCommodityStockRecordVo.getTotalQuantity());
        statsUserVo.setYesterdayTotalCostPrice(statsCommodityStockRecordVo.getTotalCostPrice());
        statsUserVo.setYesterdayTotalProfit(SciCalUtils.sciCalToBD(statsCommodityStockRecordVo.getTotalRetailPrice().subtract(statsCommodityStockRecordVo.getTotalCostPrice()), 2));
        log.info("userVo：{}", JSON.toJSONString(userVo));
        log.info("getTurnover：{}", userVo.getTurnover());
        log.info("getQuantityOfCoinsSold：{}", userVo.getQuantityOfCoinsSold());
        log.info("getOrderCount：{}", userVo.getOrderCount());
        statsUserVo.setYesterdayTotalAmount(userVo.getTurnover());
        statsUserVo.setYesterdayTotalQuantityOfCoinsSold(userVo.getQuantityOfCoinsSold());
        statsUserVo.setYesterdayTotalOrderCount(userVo.getOrderCount());

        /**
         * 返回当天数据
         * */
        BigDecimal totalMoney = orderVoMoney.getTotalAmount();
        //利润 = 成交金额 - 商品成本
        statsUserVo.setTotalProfit(SciCalUtils.sciCalToBD(totalMoney.subtract(totalCostPrice), 2));
        statsUserVo.setTotalAmount(totalMoney);
        statsUserVo.setTotalCount(orderVoMoney.getOrderCount());
        statsUserVo.setQuantityOfCoinsSold(0);
        statsUserVo.setCommodityCount(orderItemVo.getCommodityCount());
        statsUserVo.setTotalCostPrice(totalCostPrice);
        statsUserVo.setTotalDevice(deviceVo.getTotalDevice());
        statsUserVo.setOnlineCount(deviceVo.getOnlineCount());
        statsUserVo.setOfflineCount(deviceVo.getOfflineCount());
        statsUserVo.setLackTotalStockNumber(displayRackItemVo.getLackTotalStockNumber());

        /**
         * 总订单销售额
         * */
        statsUserVo.setOrderTotalTurnover(userVo.getOrderTotalTurnover().add(totalMoney));
        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse findReturnedItems(Long orderId) {
        Order order = orderDao.findByOrderId(orderId);
          /*
          是否符合游戏币,人民币余额条件
          mchType=1.自有商户，3.现金收款，4.余额支付，7.线下收款码 AND typeOfArrival=1.存储在余额
         */
        OrderItemDto orderItemDto = OrderItemDto.builder()
                .orderId(orderId)
                .build();
        if ((order.getMchType().equals(MchTypeEnum.OWN.getCode()) || order.getMchType().equals(MchTypeEnum.CASH_RECEIPTS.getCode()) ||
                order.getMchType().equals(MchTypeEnum.BALANCE_PAYMENT.getCode()) || order.getMchType().equals(MchTypeEnum.OFFLINE_COLLECTION_CODE.getCode()))
                && OrderTypeOfArrivalEnum.SAVE_TO_BALANCE.getCode().equals(order.getTypeOfArrival())) {

            List<Integer> typeList = new ArrayList<>();
            typeList.add(CommodityTypeEnum.REGULAR.getCode());
            typeList.add(CommodityTypeEnum.PACKAGE.getCode());
            typeList.add(CommodityTypeEnum.RECHARGE_BALANCE.getCode());
            orderItemDto.setTypeList(typeList);
            List<OrderItemVo> productDetails = orderItemService.findProductDetails(orderItemDto);
            return ServerResponse.createBySuccess(productDetails);
        }
        /*
         * 是否符合售货机条件
         * deviceTypeId=23,24,25,31 售货机类型 AND shipmentStatus=1 出货成功
         */
        else if ((DeviceTypeEnum.VENDING_MACHINE.getCode().equals(order.getDeviceTypeId()) || DeviceTypeEnum.SCREEN_VENDING_MACHINE.getCode().equals(order.getDeviceTypeId()) ||
                DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode().equals(order.getDeviceTypeId()) || DeviceTypeEnum.BLEND_VENDING_MACHINE.getCode().equals(order.getDeviceTypeId()))
                && (ShipmentStatusEnum.SUCCESS.getCode().equals(order.getShipmentStatus()) || ShipmentStatusEnum.FAIL.getCode().equals(order.getShipmentStatus()))) {
            List<Integer> typeList = new ArrayList<>();
            typeList.add(CommodityTypeEnum.CURRENT.getCode());
            orderItemDto.setTypeList(typeList);
            List<OrderItemVo> productDetails = orderItemService.findProductDetails(orderItemDto);
            return ServerResponse.createBySuccess(productDetails);
        }
        return ServerResponse.createBySuccess();
    }

    @Override
    public List<OrderVo> findOrderStoreListByBranch(OrderDto orderDto) {
        return orderDao.findOrderStoreListByBranch(orderDto);
    }

    @Override
    public List<OrderVo> findOrderStoreListByBranchScanCode(OrderDto orderDto) {
        return orderDao.findOrderStoreListByBranchScanCode(orderDto);
    }
}
